﻿using System;

namespace Net.Formats.oEmbed
{
    /// <summary>
    /// Responses can specify a resource type, such as photo or video. 
    /// Providers may optionally include any parameters not specified
    /// and consumers may choose to ignore these. 
    /// Consumers must ignore parameters they do not understand.
    /// </summary>
    public abstract class GenericResponse
    {
        #region Private Fields

        ResponseType type;
        string version;
        string title;
        string authorName;
        Uri authorUrl;
        string providerName;
        Uri providerUrl;
        int? cacheAge;
        Uri thumbnailUrl;
        int? thumbnailWidth;
        int? thumbnailHeight;

        #endregion

        #region Class Constructor

        public GenericResponse( ResponseType type )
        {
            this.type = type;
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// The resource type. Required.
        /// </summary>
        public ResponseType Type
        {
            get { return type; }            
        }

        /// <summary>
        /// The oEmbed version number. This must be 1.0. Required.
        /// </summary>
        public string Version
        {
            get { return version; }
            set
            {
                if ( value != "1.0" )
                    throw new NotSupportedException( "According to specification, version value should be 1.0" );
                if ( version != value )
                    version = value;
            }
        }

        /// <summary>
        /// A text title, describing the resource. Optional.
        /// </summary>
        public string Title
        {
            get { return title; }
            set
            {
                if ( title != value )
                    title = value;
            }
        }

        /// <summary>
        /// The name of the author/owner of the resource. Optional.
        /// </summary>
        public string AuthorName
        {
            get { return authorName; }
            set
            {
                if ( authorName != value )
                    authorName = value;

            }
        }

        /// <summary>
        /// A URL for the author/owner of the resource. Optional.
        /// </summary>
        public Uri AuthorUrl
        {
            get { return authorUrl; }
            set
            {
                if ( authorUrl != value )
                    authorUrl = value;
            }
        }

        /// <summary>
        /// The name of the resource provider. Optional.
        /// </summary>
        public string ProviderName
        {
            get { return providerName; }
            set
            {
                if ( providerName != value )
                    providerName = value;
            }

        }

        /// <summary>
        /// The url of the resource provider. Optional.
        /// </summary>
        public Uri ProviderUrl
        {
            get { return providerUrl; }
            set
            {
                if ( providerUrl != value )
                    providerUrl = value;
            }
        }

        /// <summary>
        /// The suggested cache lifetime for this resource, in seconds. 
        /// Consumers may choose to use this value or not. Optional.
        /// </summary>
        public int? CacheAge
        {
            get { return cacheAge; }
            set
            {
                if ( cacheAge != value )
                    cacheAge = value;
            }
        }

        /// <summary>
        /// A URL to a thumbnail image representing the resource. 
        /// The thumbnail must respect any maxwidth and maxheight parameters. 
        /// If this paramater is present, thumbnail_width and thumbnail_height must also 
        /// be present.
        /// </summary>
        public Uri ThumbnailUrl
        {
            get
            {
                ValidateThumbnailParameters( );
                return thumbnailUrl;
            }
            set
            {
                if ( thumbnailUrl != value )
                    thumbnailUrl = value;
            }
        }

        /// <summary>
        /// The width of the optional thumbnail. 
        /// If this paramater is present, thumbnail_url  and thumbnail_height must also 
        /// be present.
        /// </summary>
        public int? ThumbnailWidth
        {
            get
            {
                ValidateThumbnailParameters( );
                return thumbnailWidth;
            }
            set
            {
                if ( thumbnailWidth != value )
                    thumbnailWidth = value;
            }
        }

        /// <summary>
        /// The height of the optional thumbnail. If this paramater is present, 
        /// thumbnail_url  and thumbnail_width must also be present.
        /// </summary>
        public int? ThumbnailHeight
        {
            get
            {
                ValidateThumbnailParameters( );
                return thumbnailHeight;
            }        
            set
            {
                if ( thumbnailHeight != value )
                    thumbnailHeight = value;                
            }
        }

        #endregion

        #region Private Methods

        void ValidateThumbnailParameters( )
        {
            var val = 0;
            string properties = string.Empty;

            if ( thumbnailHeight == null)
                properties = "ThumbnailHeight";
            else 
                val++;                
            
            if (thumbnailWidth == null)
                properties = properties + ", ThumbnailWidth";
            else 
                val++;

            if ( thumbnailUrl == null )
                properties = properties + ", ThumbnailUrl";
            else
                val++;

            if (val >= 1 && val <=2)
                throw new ArgumentNullException("Thumbnail properties", properties + " must be specified" );
        }

        #endregion
    }
}
